home *** CD-ROM | disk | FTP | other *** search
/ Meeting Pearls 2 / Meeting Pearls Vol. II (1995)(GTI - Schatztruhe)[!].iso / Pearls / comm / Envoy / Talk / talk.c < prev    next >
C/C++ Source or Header  |  1994-04-17  |  16KB  |  291 lines

  1. /*************************************************************************
  2. Talk Client written by Jeffrey A. Litz for Envoy Talk Service
  3.  
  4. litz@cs.uwp.edu  -or-  Jeff_Litz@EDTNG.Kenosha.WI.US
  5.  
  6. Copyright ©1994 JL Productions.
  7. *************************************************************************/
  8.  
  9. #include <exec/types.h>
  10. #include <exec/memory.h>
  11. #include <exec/ports.h>
  12. #include <exec/semaphores.h>
  13. #include <envoy/nipc.h>
  14. #include <envoy/services.h>
  15. #include <pragmas/exec_pragmas.h>
  16. #include <pragmas/nipc_pragmas.h>
  17. #include <pragmas/dos_pragmas.h>
  18. #include <pragmas/services_pragmas.h>
  19.  
  20. #include <utility/tagitem.h>
  21. #include <clib/dos_protos.h>
  22. #include <clib/exec_protos.h>
  23. #include <clib/nipc_protos.h>
  24. #include <clib/services_protos.h>
  25. #include <clib/alib_protos.h>
  26. #include <clib/alib_stdio_protos.h>
  27.  
  28. #include <string.h>
  29.  
  30. #define geta4 __builtin_geta4
  31. void geta4(void);
  32.  
  33. #define TKCMD_TALK  1
  34. #define TKCMD_ABORT 2
  35. #define TKCMD_DATA  3
  36.  
  37. struct Library *SysBase,*DOSBase,*NIPCBase,*ServicesBase;
  38.  
  39. static UBYTE version[32] = {"$VER: Talk Client v1.2a"};
  40.  
  41. void _main(void)
  42. {
  43.     struct RDArgs *lpargs;
  44.     void *entity, *dest, *a_entity;
  45.     struct Transaction *trans,*a_trans;
  46.     ULONG sigbit=0,sigbit2=0,waitmask,signal,howmany;
  47.     ULONG args[1];
  48.     BPTR input_w,output_w;
  49.     ULONG done=0;
  50.     UBYTE work_space[512],host_name[256],userinput[256];
  51.     struct MsgPort *port,*replyport;
  52.     struct StandardPacket *packet;
  53.     struct TagItem cetags[4],cbtags[2],ttags[3];
  54.     
  55.     geta4();
  56.     SysBase = *((struct Library **)4L);
  57.  
  58.     /* Initialize a bunch of stuff for setting up transactions */
  59.  
  60.     cetags[0].ti_Tag=ENT_Name;
  61. /* Assigned later */
  62. //  cetags[0].ti_Data=NULL;
  63.     cetags[1].ti_Tag=ENT_Public;
  64.     cetags[1].ti_Data=NULL;
  65.     cetags[2].ti_Tag=ENT_AllocSignal;
  66.     cetags[2].ti_Data=(ULONG) &sigbit;
  67.     cetags[3].ti_Tag=TAG_END;
  68.     cetags[3].ti_Data=0;
  69.  
  70.     cbtags[0].ti_Tag=ENT_AllocSignal;
  71.     cbtags[0].ti_Data=(ULONG) &sigbit2;
  72.     cbtags[1].ti_Tag=TAG_END;
  73.     cbtags[1].ti_Data=0;
  74.  
  75.     ttags[0].ti_Tag=TRN_AllocReqBuffer;
  76.     ttags[0].ti_Data=516;
  77.     ttags[1].ti_Tag=TRN_AllocRespBuffer;
  78.     ttags[1].ti_Data=4;
  79.     ttags[2].ti_Tag=TAG_END;
  80.     ttags[2].ti_Data=0;
  81.  
  82.     /* open up dos library */
  83.     if(DOSBase=OpenLibrary("dos.library", 37L))
  84.     {
  85.         /* Check to see if a machine to talk to was specified */
  86.         args[0]=0;
  87.         if(lpargs=ReadArgs("Server/A",args,NULL))
  88.         {
  89.             /* open up nipc library */
  90.             if(NIPCBase=OpenLibrary("nipc.library", 0L))
  91.             {
  92.                 /* open up services library */
  93.                 if(ServicesBase=OpenLibrary("services.library", 37L))
  94.                 {
  95.                     /* create a "near" side entity - to SEND data to service */
  96.                     if(entity=CreateEntityA((struct TagItem *) cbtags))
  97.                     {
  98.                         /* Find out exactly who WE are */
  99.                         GetHostName(entity,host_name,255);
  100.  
  101.                         /* Setup our entity name */
  102.                         cetags[0].ti_Data=(ULONG) "talk_back";
  103.  
  104.                         /* create a "far" side entity - to RECEIVE data from service */
  105.                         if(a_entity=CreateEntityA((struct TagItem *) cetags))
  106.                         {
  107.                            /* create a transaction for sending data to service */
  108.                            if(trans=AllocTransactionA((struct TagItem *) ttags))
  109.                            {
  110.                               /* Locate the service */
  111.                               if(dest=FindServiceA((UBYTE *)args[0], "Talk_Service", entity, NULL))
  112.                               {
  113.                                  /*
  114.                                  ** OK - found, now setup a transaction to
  115.                                  ** send to the talk service to request a
  116.                                  ** talk with us
  117.                                  */
  118.                                  
  119.                                  *(ULONG *)(trans->trans_RequestData)=*(ULONG *)(trans->trans_ResponseData);
  120.                                  strcpy(((UBYTE *)trans->trans_RequestData+4),host_name);
  121.                                  trans->trans_ReqDataActual=strlen(host_name)+4;
  122.                                  trans->trans_Command=TKCMD_TALK;
  123.                                  trans->trans_Timeout=10;
  124.                                  DoTransaction(dest,entity,trans);
  125.                                  
  126.                                  /* Was there any type of transaction error? */
  127.                                  if(trans->trans_Error==0)
  128.                                  {
  129.                                     /* Everything went OK, *PLUS* the person wishes to talk with us */
  130.                                     /* Open up the input and output windows */
  131.                                     if(output_w=(BPTR)Open("CON:0/0/640/150/Output Window",MODE_NEWFILE))
  132.                                     {
  133.                                        if(input_w=(BPTR)Open("CON:0/150/640/50/Input Window/CLOSE",MODE_NEWFILE))
  134.                                        {
  135.                                           /*
  136.                                           ** Setup everything for reading
  137.                                           ** from the input window using
  138.                                           ** packets
  139.                                           */
  140.                                           
  141.                                           /* Create a packet for reading the keyboard */
  142.                                           if(packet=(struct StandardPacket *)AllocMem((long)sizeof(struct StandardPacket),MEMF_PUBLIC|MEMF_CLEAR))
  143.                                           {
  144.                                              port=(struct MsgPort *) (((struct FileHandle *)((ULONG)input_w<<2))->fh_Type);
  145.                                              if(replyport=(struct MsgPort *) CreatePort(NULL,0))
  146.                                              {
  147.                                                 packet->sp_Msg.mn_Node.ln_Name=(char *)&(packet->sp_Pkt);
  148.                                                 packet->sp_Pkt.dp_Link=&(packet->sp_Msg);
  149.                                                 packet->sp_Pkt.dp_Port=replyport;
  150.                                                 packet->sp_Pkt.dp_Type=ACTION_WAIT_CHAR;
  151.                                                 packet->sp_Pkt.dp_Arg1=34000;
  152.                                                 SendPkt(&packet->sp_Pkt,port,replyport);
  153.                                           
  154.                                                 /*
  155.                                                 ** set the wait mask for a
  156.                                                 ** wait for character from
  157.                                                 ** the input window and for
  158.                                                 ** any incoming transactions
  159.                                                 */
  160.                                                 
  161.                                                 waitmask = (1<<replyport->mp_SigBit) | (1<<sigbit);
  162.                                           
  163.                                                 while(!done)
  164.                                                 {
  165.                                                    signal = Wait(waitmask);
  166.                                                    
  167.                                                    /* Was there keyboard input? */
  168.                                                    if(signal & (1<<replyport->mp_SigBit))
  169.                                                    {  
  170.                                                       /* check to make sure */
  171.                                                       if(GetMsg(replyport))
  172.                                                       {
  173.                                                          /* check again */
  174.                                                          if(packet->sp_Pkt.dp_Res1)
  175.                                                          {
  176.                                                             /* read the input */
  177.                                                             if(!(howmany=Read(input_w,userinput,255)))
  178.                                                             {
  179.                                                                /* close gadget - signal shut down */
  180.                                                                done=2;
  181.                                                             } else
  182.                                                             {
  183.                                                                /* Send input to our output window and send a transaction to the service to be displayed on the other side */
  184.                                                                userinput[howmany]=0;
  185.                                                                sprintf(work_space,"(%s) %s\n",host_name,userinput);
  186.                                                                Write(output_w,work_space,strlen(work_space));
  187.                                                                trans->trans_Command=TKCMD_DATA;
  188.                                                                *(ULONG *)(trans->trans_RequestData)=*(ULONG *)(trans->trans_ResponseData);
  189.                                                                strcpy(((UBYTE *)trans->trans_RequestData+4),work_space);
  190.                                                                trans->trans_ReqDataActual=strlen(work_space)+4;
  191.                                                                trans->trans_Timeout=10;
  192.                                                                DoTransaction(dest,entity,trans);
  193.                                                             }
  194.                                                          }
  195.                                                          /* setup another packet for wait for character */
  196.                                                          packet->sp_Pkt.dp_Port=replyport;
  197.                                                          packet->sp_Pkt.dp_Type=ACTION_WAIT_CHAR;
  198.                                                          packet->sp_Pkt.dp_Arg1=34000;
  199.                                                          SendPkt(&packet->sp_Pkt,port,replyport);
  200.                                                       }
  201.                                                    }
  202.                                                    /* was there a transaction? */
  203.                                                    if(signal & (1<<sigbit))
  204.                                                    {
  205.                                                       /* get the transaction */
  206.                                                       if(a_trans=GetTransaction(a_entity))
  207.                                                       {
  208.                                                          /* was it a data transaction or close down transaction */
  209.                                                          if(a_trans->trans_Command == TKCMD_DATA)
  210.                                                          {
  211.                                                             Write(output_w,(UBYTE *)((UBYTE *)a_trans->trans_RequestData+4),a_trans->trans_ReqDataActual-4);
  212.                                                          } else if(a_trans->trans_Command == TKCMD_ABORT)
  213.                                                          {
  214.                                                             done=1;
  215.                                                          }
  216.                                                          
  217.                                                          /* reply to the DoTransaction() from the other side */
  218.                                                          ReplyTransaction(a_trans);
  219.                                                       }
  220.                                                    }
  221.                                                 }
  222.                                                 /* Attempt to clear out any "left over" packet messages */
  223.                                                 while((ULONG *)GetMsg(replyport) != (ULONG *)&packet->sp_Msg);
  224.                                                 DeletePort(replyport);
  225.                                              }
  226.                                              /* Free up packet allocation */
  227.                                              FreeMem(packet,(long)sizeof(struct StandardPacket));
  228.                                           }
  229.                                           /* close input and output windows */
  230.                                           Close(input_w);
  231.                                        }
  232.                                        Close(output_w);
  233.                                     }
  234.                                     /* If we initiated the close down - attempt to signal other side to prevent a "hang" */
  235.                                     if(done == 2)
  236.                                     {
  237.                                        /* Just trying to make sure the TKCMD_ABORT gets through */
  238.                                        
  239.                                        howmany=4;
  240.                                        while(howmany--)
  241.                                        {
  242.                                           trans->trans_ReqDataActual=4;
  243.                                           trans->trans_Command=TKCMD_ABORT;
  244.                                           trans->trans_Timeout=10;
  245.                                           DoTransaction(dest,entity,trans);
  246.                                           if(trans->trans_Error == 0)
  247.                                           {
  248.                                                 break;
  249.                                           }
  250.                                        }
  251.                                     }
  252.                                  } else if(trans->trans_Error == 1)
  253.                                  {
  254.                                     /* talk service already active */
  255.                                     FPrintf(Output(),"Busy - talk already in process.\n");
  256.                                  } else if(trans->trans_Error == 2)
  257.                                  {
  258.                                     /* we were either ignored or no one was available */
  259.                                     FPrintf(Output(),"No response from talk request.\n");
  260.                                  }
  261.                                  /* lose the service */
  262.                                  LoseService(dest);
  263.                               } else
  264.                               { 
  265.                                  /* something drastically went wrong */
  266.                                  /* either machine doesn't exist or service isn't available on that machine */
  267.                                  FPrintf(Output(),"Unable to connect with the machine or service on that machine.\n");
  268.                               }
  269.                               /* free up the transaction allocation */
  270.                               trans->trans_ReqDataLength = 516;
  271.                               FreeTransaction(trans);
  272.                            }
  273.                            /* clean up - delete/close everything */
  274.                            DeleteEntity(a_entity);
  275.                         }
  276.                         DeleteEntity(entity);
  277.                      }
  278.                      CloseLibrary(ServicesBase);
  279.                 }
  280.                 CloseLibrary(NIPCBase);
  281.             }
  282.             FreeArgs(lpargs);
  283.         } else
  284.         {
  285.             /* readargs failed - no machine name provided */
  286.             FPrintf(Output(),"Must provide a machine name to talk to.\n");
  287.         }
  288.         CloseLibrary(DOSBase);
  289.     }
  290. }
  291.